/*
 * @Author:
 * @Date: 2023-08-03 22:36:49
 * @LastEditors: xxx
 * @LastEditTime: 2023-08-06 16:13:52
 * @Description: 缓存消息模块，处理设备操作需要时间暂时不回复消息的情况
 * email:
 * Copyright (c) 2023 by xxx, All Rights Reserved.
 */

#include "./inc/hart_frame.h"
#include <stdlib.h>
#include <time.h>

#define HART_CACHE_LEN 1U
sqqueue_ctrl_t cache;

#ifndef STM32
static uint32_t sys_millis(void)
{
    return 0;
}
#else
#include "delay.h"
#endif

// 缓存消息初始化
void hart_cache_init(void)
{
    // srand((unsigned)time(NULL));                                     // 初始化随机数种子
    sqqueue_ctrl_init(&cache, sizeof(hart_cache_t), HART_CACHE_LEN); // 初始化队列
}

// 向缓存中添加数据
void hart_cache_add(hart_cache_t data)
{
    hart_cache_t *e;
    if (cache.get_len(&cache) >= HART_CACHE_LEN)
    {
        return; // 缓存已满
    }

    e = (hart_cache_t *)osel_mem_alloc(sizeof(hart_cache_t)); // 申请内存

    osel_memcpy((uint8_t *)e, (uint8_t *)&data, sizeof(hart_cache_t)); // 拷贝数据

    if (data.uuid == 0)
    {
        // data.uuid = rand(); // 生成随机数
        return;
    }

    e->uuid = data.uuid;
    cache.enter(&cache, (void *)e); // 入队
}

// 释放缓存数据
void hart_cache_free(hart_cache_t *data)
{
    if (data != NULL)
    {
        osel_mem_free(data);
    }
}

// 从缓存中获取数据
hart_cache_t *hart_cache_get(uint64_t uuid)
{
    hart_cache_t *e;
    uint16_t len = cache.get_len(&cache);

    if (len == 0)
    {
        return NULL; // 缓存为空
    }
    for (uint8_t i = 0; i < len; i++)
    {
        e = ((hart_cache_t *)cache.del(&cache));
        if (e->uuid == uuid)
        {
            return e;
        }
        else
        {
            cache.enter(&cache, e);
        }
    }
    return NULL;
}

/**
 * @brief 将指定的uuid对应的数据从缓存区移除
 * @param {uint64_t} uuid
 * @return {*}
 * @note
 */
void hart_cache_remove(uint64_t uuid)
{
    hart_cache_get(uuid);
}

/**
 * @brief 检查HART缓存区是否存活
 * @return {*}
 * @note
 */
void hart_cache_detection(void)
{
    hart_cache_t *e;
    uint16_t len = cache.get_len(&cache);

    if (len == 0)
    {
        return; // 缓存为空
    }
    for (uint8_t i = 0; i < len; i++)
    {
        e = ((hart_cache_t *)cache.del(&cache));

        uint32_t now = sys_millis();

        if (now <= e->hart_cache_time) // 存活
        {
            cache.enter(&cache, e);
            continue;
        }
        else // 死亡
        {
            continue;
        }
    }
}
